use serialize::json;
use curl::http;
+use git2;
use core::source::Source;
use core::{Package, MultiShell, SourceId};
let registry_src = SourceId::for_registry(&url);
let url = format!("{}/packages/new", host.trim_right_chars('/'));
- let mut handle = http::handle();
+ let mut handle = try!(http_handle());
let mut req = handle.post(url.as_slice(), &mut tarball)
.content_length(stat.size as uint)
.content_type("application/x-tar")
Ok(UploadConfig { host: host, token: token })
}
+/// Create a new HTTP handle with appropriate global configuration for cargo.
+pub fn http_handle() -> CargoResult<http::Handle> {
+ Ok(match try!(http_proxy()) {
+ Some(proxy) => http::handle().proxy(proxy),
+ None => http::handle(),
+ })
+}
+
+/// Find a globally configured HTTP proxy if one is available.
+///
+/// Favor cargo's `http.proxy`, then git's `http.proxy`, then finally a
+/// HTTP_PROXY env var.
+pub fn http_proxy() -> CargoResult<Option<String>> {
+ let configs = try!(config::all_configs(os::getcwd()));
+ match configs.find_equiv(&"http") {
+ Some(http) => {
+ let http = try!(http.table().chain_error(|| {
+ internal("invalid configuration for the key `http`")
+ }));
+ match http.find_equiv(&"proxy") {
+ Some(proxy) => {
+ return Ok(Some(try!(proxy.string().chain_error(|| {
+ internal("invalid configuration for key `http.proxy`")
+ })).ref0().to_string()))
+ }
+ None => {},
+ }
+ }
+ None => {}
+ }
+ match git2::Config::open_default() {
+ Ok(cfg) => {
+ match cfg.get_str("http.proxy") {
+ Ok(s) => return Ok(Some(s.to_string())),
+ Err(..) => {}
+ }
+ }
+ Err(..) => {}
+ }
+ Ok(os::getenv("HTTP_PROXY"))
+}
+
pub fn upload_login(shell: &mut MultiShell, token: String) -> CargoResult<()> {
let config = try!(Config::new(shell, None, None));
let UploadConfig { host, token: _ } = try!(upload_configuration());
pub use self::cargo_test::{run_tests, run_benches, TestOptions};
pub use self::cargo_package::package;
pub use self::cargo_upload::{upload, upload_configuration, UploadConfig};
-pub use self::cargo_upload::upload_login;
+pub use self::cargo_upload::{upload_login, http_proxy, http_handle};
mod cargo_clean;
mod cargo_compile;
cache_path: Path,
src_path: Path,
config: &'a mut Config<'b>,
- handle: http::Handle,
+ handle: Option<http::Handle>,
sources: Vec<PathSource>,
hashes: HashMap<(String, String), String>, // (name, vers) => cksum
}
src_path: config.registry_source_path().join(part.as_slice()),
config: config,
source_id: source_id.clone(),
- handle: http::Handle::new(),
+ handle: None,
sources: Vec::new(),
hashes: HashMap::new(),
}
try!(self.config.shell().status("Downloading", pkg));
try!(fs::mkdir_recursive(&dst.dir_path(), io::UserDir));
+ let handle = match self.handle {
+ Some(ref mut handle) => handle,
+ None => {
+ self.handle = Some(try!(ops::http_handle()));
+ self.handle.as_mut().unwrap()
+ }
+ };
// TODO: don't download into memory
- let resp = try!(self.handle.get(url.to_string()).exec());
+ let resp = try!(handle.get(url.to_string()).exec());
if resp.get_code() != 200 {
return Err(internal(format!("Failed to get 200 reponse from {}\n{}",
url, resp)))